package com.ctshk.rpc.order.goods.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.order.goods.dto.CommodityClassificationAllLevelListDTO;
import com.ctshk.rpc.order.goods.dto.CommodityClassificationDTO;
import com.ctshk.rpc.order.goods.dto.CommodityClassificationLevelTwoDTO;
import com.ctshk.rpc.order.goods.dto.ShoppingSpecialPageUrlDTO;
import com.ctshk.rpc.order.goods.entity.CommodityClassification;
import com.ctshk.rpc.order.goods.mapper.CommodityClassificationMapper;
import com.ctshk.rpc.order.goods.req.CommodityClassificationAddReq;
import com.ctshk.rpc.order.goods.req.CommodityClassificationPageReq;
import com.ctshk.rpc.order.goods.service.ICommodityClassificationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品分类 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-08
 */
@Slf4j
@DubboService
public class CommodityClassificationServiceImpl extends ServiceImpl<CommodityClassificationMapper, CommodityClassification> implements ICommodityClassificationService {

    @Autowired
    private CommodityClassificationMapper mapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addCommodityClassification(CommodityClassificationAddReq addReq, Long userId) throws Exception {
        List<CommodityClassificationDTO> currentLeveData = null;
        List<String> classNames = null;
        CommodityClassification classification = new CommodityClassification();
        if (1 == addReq.getCurrentLevelPage()) {
            currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), null);
            classNames = currentLeveData.stream().map(obj -> obj.getClassificationName()).collect(Collectors.toList());
            if (classNames.contains(addReq.getClassificationName())) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23025);
            }
            BeanUtils.copyProperties(addReq, classification, EntityUtil.getNullPropertyNames(addReq));
            classification.setClassificationLevel(addReq.getCurrentLevelPage());
        } else {
            if (null == addReq.getParentId()) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23026);
            }
            currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), addReq.getParentId());
            classNames = currentLeveData.stream().map(obj -> obj.getClassificationName()).collect(Collectors.toList());
            if (classNames.contains(addReq.getClassificationName())) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23027);
            }
            BeanUtils.copyProperties(addReq, classification, EntityUtil.getNullPropertyNames(addReq));
            classification.setClassificationLevel(2); // 不是一級分類添加，一定為2級分類
        }
        LocalDateTime now = LocalDateTime.now();
        classification.setIsDisplay(addReq.getIsDisplay());
        classification.setSort(addReq.getSort());
        classification.setStatus(addReq.getStatus());
        classification.setCreateId(userId);
        classification.setGmtCreate(now);
        classification.setModifiedId(userId);
        classification.setGmtModified(now);
        classification.setIsDeleted(IsDeletedCode.NO.getCode());
        mapper.insert(classification);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCommodityClassification(CommodityClassificationAddReq addReq, Long userId) throws Exception {
        List<CommodityClassificationDTO> currentLeveData = null;
        LocalDateTime now = LocalDateTime.now();
        Map<String, Long> map = new HashMap<String, Long>();
        CommodityClassification dbClassification = mapper.selectById(addReq.getId());
        BeanUtils.copyProperties(addReq, dbClassification, EntityUtil.getNullPropertyNames(addReq));
        if (null != addReq.getCurrentLevelPage() && 1 == addReq.getCurrentLevelPage()) {
            currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), null);
            map = currentLeveData.stream().collect(Collectors.toMap(CommodityClassificationDTO::getClassificationName, CommodityClassificationDTO::getId));
            if (map.containsKey(dbClassification.getClassificationName())) {
                Long key = map.get(dbClassification.getClassificationName());
                if (key.longValue() != dbClassification.getId().longValue()) {
                    throw new BusinessException(SystemError.MALL_MERCHANDISE_23025);
                }
            }
        } else {
            if (null == addReq.getParentId()) {
                throw new BusinessException(SystemError.MALL_MERCHANDISE_23026);
            }
            currentLeveData = mapper.findCommodityClassificationByLevel(addReq.getCurrentLevelPage(), addReq.getParentId());
            map = currentLeveData.stream().collect(Collectors.toMap(CommodityClassificationDTO::getClassificationName, CommodityClassificationDTO::getId));
            if (map.containsKey(dbClassification.getClassificationName())) {
                Long key = map.get(dbClassification.getClassificationName());
                if (key.longValue() != dbClassification.getId().longValue()) {
                    throw new BusinessException(SystemError.MALL_MERCHANDISE_23027);
                }
            }
            // 修改子集，父级对象也更新修改时间
            CommodityClassification commodityClassification = new CommodityClassification();
            commodityClassification.setModifiedId(userId);
            commodityClassification.setGmtModified(now);
            commodityClassification.setId(addReq.getParentId());
            mapper.updateById(commodityClassification);
        }
        dbClassification.setModifiedId(userId);
        dbClassification.setGmtModified(now);
        mapper.updateById(dbClassification);
    }

    @Override
    public PageResponse<CommodityClassificationDTO> findCommodityClassification(
            CommodityClassificationPageReq pageReq, TokenUser tokenUser) {
        IPage<CommodityClassificationDTO> page = new Page<CommodityClassificationDTO>(pageReq.getPageNo(), pageReq.getPageSize());
        IPage<CommodityClassificationDTO> iPage = mapper.findCommodityClassificationByCondition(page, pageReq);
        List<CommodityClassificationDTO> recordsList = iPage.getRecords();
        List<CommodityClassificationDTO> pageDTOList = EntityUtil.copyList(recordsList, CommodityClassificationDTO.class);
        return new PageResponse<>(pageDTOList, iPage.getCurrent() == 1,
                iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()),
                iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public List<CommodityClassificationDTO> findClassificationNameList() {
        return mapper.findOneLeveClassificationNameList();
    }

    @Override
    public List<CommodityClassificationAllLevelListDTO> findClassificationByAllLevel(LocalDateTime now) {
        // 查询一级菜单
        List<CommodityClassificationAllLevelListDTO> dbLevelOneData = mapper.findClassificationByLevelOne(now);

        // 查询二级菜单
        List<CommodityClassificationLevelTwoDTO> dbLevelTwoData = mapper.findClassificationByLevelTwo(now);
        Map<String, List<CommodityClassificationLevelTwoDTO>> levelTwo = new HashMap<>();
        if (CollectionUtils.isNotEmpty(dbLevelTwoData)) {
            log.info("【查询二级菜单，数据返参为:{}】", JSON.toJSONString(dbLevelOneData));
            levelTwo = dbLevelTwoData.stream().collect(Collectors.groupingBy(levelOjb -> levelOjb.getParentId().toString()));
        }
        if (CollectionUtils.isNotEmpty(dbLevelOneData)) {
            log.info("【查询一级菜单，数据返参为:{}】", JSON.toJSONString(dbLevelOneData));
            for (CommodityClassificationAllLevelListDTO levelOne : dbLevelOneData) {
                levelOne.setLevelTwo(null);
                if (levelTwo.containsKey(levelOne.getId().toString())) {
                    List<CommodityClassificationLevelTwoDTO> levelTwos = levelTwo.get(levelOne.getId().toString());
                    levelOne.setLevelTwo(levelTwos);
                }
            }
            for (CommodityClassificationAllLevelListDTO levelOneDatum : dbLevelOneData) {
                if (CollectionUtils.isNotEmpty(levelOneDatum.getLevelTwo())) {
                    for (CommodityClassificationLevelTwoDTO levelTwoDTO : levelOneDatum.getLevelTwo()) {
                        if (null != levelTwoDTO.getIcon()) {
                            List<ShoppingSpecialPageUrlDTO> list = JSON.parseArray(levelTwoDTO.getIcon(), ShoppingSpecialPageUrlDTO.class);
                            levelTwoDTO.setIcon(list.get(0).getUrl());
                        }
                    }
                }
            }
        }
        return dbLevelOneData;
    }
}
